package hyl.xsdk.flutter.plugin.xsdk_flutter_plugin;

import android.content.Context;
import android.view.Display;

import androidx.annotation.NonNull;

import com.sunmi.XShangMiUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.List;
import java.util.Map;


import android.content.Intent;
import android.content.IntentFilter;

import hyl.xsdk.flutter.plugin.xsdk_flutter_plugin.base.XBeanPluginMethod;
import hyl.xsdk.flutter.plugin.xsdk_flutter_plugin.second_screen.XSecondScreen_flutter_webview_reabam;
import hyl.xsdk.sdk.api.android.Android_API;
import hyl.xsdk.sdk.api.android.other_api.eventbus.XEventBusUtils;
import hyl.xsdk.sdk.api.android.other_api.eventbus.XEvent_EventBus;
import hyl.xsdk.sdk.api.android.other_api.usb.XSerialPortConnectApi;
import hyl.xsdk.sdk.api.android.utils.L;
import hyl.xsdk.sdk.api.android.utils.XStringUtils;
import hyl.xsdk.sdk.api.android.utils.json.XJsonUtils;
import hyl.xsdk.sdk.api.android.utils.second_screen.XSecondScreenUtils;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import top.keepempty.sph.library.SphCmdEntity;

import com.zhongqi.xsdk.XZhongQiUtils;
import com.zhongqi.xsdk.ZQSerialWeigherCallback;

import com.zhifubao.xsdk.XAlipayIotUtils2;
import com.zhifubao.xsdk.XAlipayIotCallback;

import android.app.Activity;

/**
 XsdkFlutterPlugin
 注意: 插件不需要手动在activity中注册,引用时自动完成注册

 注意:不能使用aar文件,因为在实际开发项目中提示找不到aar(如在实际开发项目中的libs文件夹中放入aar,则提示runtime包重复冲突),
 因此使用jar替代aar(即纯代码,没有xml等素材),在开发项目中也不需要再放入jar文件了,直接依赖xsdk_flutter_plugin即可使用;

 主要用于flutter库没有的第三方库的调用(如果flutter有,则一概使用flutter库)

 */
public class XSDKFlutterPlugin implements FlutterPlugin,ActivityAware, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private Context applicationContext;
  private Activity activity;
  private Android_API api;

  //初始化
  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    //init
    applicationContext=flutterPluginBinding.getApplicationContext();
    api = Android_API.getInstance(applicationContext);
    L.sdk("---Android,AppName="+api.getAppName()+",AppVersion="+api.getAppVersionName());
    //
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "xsdk_flutter_plugin");
    channel.setMethodCallHandler(this);

    //
    XEventBusUtils.registerEventBus(this);

  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
    XEventBusUtils.unregisterEventBus(this);
  }

  @Override
  public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
    activity = binding.getActivity();
    L.sdk("---onAttachedToActivity="+activity.getClass().getName());
  }

  @Override
  public void onDetachedFromActivity() {
    //this.activity = null;
    L.sdk("---onDetachedFromActivity");
  }

  @Override
  public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
    L.sdk("---onReattachedToActivityForConfigChanges");
    onAttachedToActivity(binding);
  }

  @Override
  public void onDetachedFromActivityForConfigChanges() {
    L.sdk("---onDetachedFromActivityForConfigChanges");
    onDetachedFromActivity();
  }

  @Subscribe(threadMode = ThreadMode.MAIN)
  public void onEventBusListener(XEvent_EventBus event) {
    L.sdk("---EventBus收到:"+XJsonUtils.obj2String(event));
    nativeSendMessageToFlutter(event.tag,XJsonUtils.obj2String(event.obj));
  }

  //原生发送通知flutter
  private void nativeSendMessageToFlutter(String method, Object arguments){
    channel.invokeMethod(method,arguments);
  }

  //设置接收flutter通知原生
  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    L.sdk("--- flutter调用xsdk_android方法: onMethodCall: method= "+call.method+",arguments= "+call.arguments.toString());
    try{

      if (call.method.equals("XShangMi")) {
        //商米机sdk
        methodCall_XShangMi(call,result);
      }else if (call.method.equals("XSerialPort")) {
        //4线 串口电子秤 商米机,中崎
        methodCall_SerialPort(call,result);
      }else if (call.method.equals("XManualSystemLoadLibrary")) {
        try{
          if(android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.M){
            L.sdk("---手动加载.so文件,适用android 6.0");
            //手动加载.so文件,适用android 6.0, 如:objectbox-jni.so
            String json=call.arguments.toString();
            XBeanPluginMethod methodCommand= XJsonUtils.json2Obj(json, XBeanPluginMethod.class);
            //.so文件名称(不包括.so后续),如: objectbox-jni
            String soName=methodCommand.type;
            L.sdk("---加载.so文件="+soName);
            if(!XStringUtils.isEmpty(soName)){
              //System.loadLibrary("objectbox-jni");
              System.loadLibrary(soName);
            }
          }

        }catch (Exception e){
          L.sdk(e);
        }

        result.success("");

      }else if (call.method.equals("XUsb")) {
        //usb
        methodCall_Usb(call,result);
      }else if (call.method.equals("XUsbSerial")) {
        //usb serial
        methodCall_UsbSerial(call,result);
      }else if (call.method.equals("XSecondScreen")) {
        //分屏,第二屏幕
        methodCall_XSecondScreen(call,result);
      }else if (call.method.equals("XAndroid")) {
        //android_api
        methodCall_XAndroid(call,result);
      }else if (call.method.equals("XAlipayIotSDK")) {
        //支付宝Iot碰一碰设备
        methodCall_XAlipayIotSDK(call,result);
      }else {
        result.notImplemented();
      }

    }catch (Exception e){
      L.sdk(e);
      //返回: result.success("failed");  result.error();
      result.notImplemented();
    }

  }


  //支付宝Iot碰一碰设备
  private void methodCall_XAlipayIotSDK(MethodCall call, Result result){
    String json_call=call.arguments.toString();
    L.sdk("---XAlipayIotSDK json:"+json_call);
    XBeanPluginMethod methodCommand= XJsonUtils.json2Obj(json_call, XBeanPluginMethod.class);

    try{
      if ("init".equalsIgnoreCase(methodCommand.type)){
        L.sdk("---h5调用XAlipayIotSDK,init初始化");
        String data= (String) methodCommand.data;
        Map<String,Object> map=XJsonUtils.jsonToMapObject(data);
        String appId=(String)map.get("appId");
        String pId=(String)map.get("pId");

        XAlipayIotUtils2.init(
                applicationContext,
                appId,
                pId,
                null,
                new XAlipayIotCallback() {
                  @Override
                  public void callback(String json) {
                    L.sdk("---XAlipayIotSDK,初始化,json="+json);
                    nativeSendMessageToFlutter("AlipayIot_init",json);
                  }
                }
        );

      }else if("commonPay".equalsIgnoreCase(methodCommand.type)){
        L.sdk("---h5调用XAlipayIotSDK,发起普通支付");
        String data= (String) methodCommand.data;
        Map<String,Object> map=XJsonUtils.jsonToMapObject(data);
        String operateType=(String)map.get("operateType");
        String amount=(String)map.get("amount");
        String tradeNo=(String)map.get("tradeNo");

        XAlipayIotUtils2.startBPaaSService_common_pay(
                operateType,
                amount,
                tradeNo,
                false,
                new XAlipayIotCallback() {
                  @Override
                  public void callback(String json) {
                    L.sdk("---XAlipayIotSDK,发起普通支付,json="+json);
                    nativeSendMessageToFlutter("AlipayIot_commonPay",json);
                  }
                }
        );

      }else if("memberPay".equalsIgnoreCase(methodCommand.type)){
        L.sdk("---h5调用XAlipayIotSDK,发起会员支付");
        String data= (String) methodCommand.data;
        Map<String,Object> map=XJsonUtils.jsonToMapObject(data);
        String operateType=(String)map.get("operateType");
        String itemAppId=(String)map.get("itemAppId");
        String templateId=(String)map.get("templateId");
        String providerId=(String)map.get("providerId");
        String outString=(String)map.get("outString");

        XAlipayIotUtils2.startBPaaSService_member_pay(
                operateType,
                providerId,
                itemAppId,
                templateId,
                outString,
                new XAlipayIotCallback() {
                  @Override
                  public void callback(String json) {
                    L.sdk("---XAlipayIotSDK,发起会员支付,json="+json);
                    nativeSendMessageToFlutter("AlipayIot_memberPay",json);
                  }
                }
        );

      }else if("memberCard".equalsIgnoreCase(methodCommand.type)){
        L.sdk("---h5调用XAlipayIotSDK,发起会员开卡");
        String data= (String) methodCommand.data;
        Map<String,Object> map=XJsonUtils.jsonToMapObject(data);
        String operateType=(String)map.get("operateType");
        String itemAppId=(String)map.get("itemAppId");
        String templateId=(String)map.get("templateId");
        String providerId=(String)map.get("providerId");
        String outString=(String)map.get("outString");

        XAlipayIotUtils2.startBPaaSService_member_createCard(
                operateType,
                providerId,
                itemAppId,
                templateId,
                outString,
                new XAlipayIotCallback() {
                  @Override
                  public void callback(String json) {
                    L.sdk("---XAlipayIotSDK,发起会员开卡,json="+json);
                    nativeSendMessageToFlutter("AlipayIot_memberCard",json);
                  }
                }
        );

      }else if("x".equalsIgnoreCase(methodCommand.type)){
        String data= (String) methodCommand.data;
        L.sdk("---h5调用XAlipayIotSDK,通用方法x,data="+data);

        Map<String,Object> map=XJsonUtils.jsonToMapObject(data);

        XAlipayIotUtils2.startBPaaSService_x(
                map,
                new XAlipayIotCallback() {
                  @Override
                  public void callback(String json) {
                    L.sdk("---XAlipayIotSDK,通用方法x,callback="+json);
                    nativeSendMessageToFlutter("AlipayIot_x",json);
                  }
                }
        );

      }

    }catch (Exception e){
      L.sdk(e);
    }

    result.success("");
  }




  //usb设备
  private void methodCall_Usb(MethodCall call, Result result){
    result.success("");
  }

  //usb serial设备
  private void methodCall_UsbSerial(MethodCall call, Result result){
    result.success("");
  }

  //分屏,第二屏幕
  Display secondScreenDisplay;
  XSecondScreen_flutter_webview_reabam secondScreenH5Dialog;
  private void methodCall_XSecondScreen(MethodCall call, Result result){
    String json=call.arguments.toString();
    L.sdk("---给分屏数据:"+json);
    XBeanPluginMethod methodCommand= XJsonUtils.json2Obj(json, XBeanPluginMethod.class);

    try{
      if ("openSecondScreen".equalsIgnoreCase(methodCommand.type)){
        L.sdk("---h5调用开启分屏");
        String url= (String) methodCommand.data;

        //分屏
        if(secondScreenDisplay==null){
          secondScreenDisplay= XSecondScreenUtils.getPresentationDisplay(applicationContext);
          //secondScreenDisplay= XSecondScreenUtils.getPresentationDisplay(activity);
        }
        //存在分屏
        if(secondScreenDisplay!=null){
          if(secondScreenH5Dialog!=null){
            secondScreenH5Dialog.dismiss();
          }

          //适配商米T2,注意: 使用applicationContext,实测:只有商米T2无法使用分屏,要用当前activity,
          //secondScreenH5Dialog=new XSecondScreen_flutter_webview_reabam(applicationContext,secondScreenDisplay,url);
          secondScreenH5Dialog=new XSecondScreen_flutter_webview_reabam(activity,secondScreenDisplay,url);
          secondScreenH5Dialog.show();
        }

      }else if ("updateSecondScreen".equalsIgnoreCase(methodCommand.type)){
        L.sdk("---h5调用刷新分屏");
        if(secondScreenH5Dialog!=null){
          secondScreenH5Dialog.refreshH5WebView();
        }
      }else if ("sengMsgToSecondScreen".equalsIgnoreCase(methodCommand.type)){
        L.sdk("---h5调用发送消息到分屏");
        String json1=(String) methodCommand.data;
        Map<String,Object> m1=XJsonUtils.jsonToMapObject(json1);
        String t2= (String) m1.get("type");


        if("shopcart".equalsIgnoreCase(t2)){
          String json2= (String) m1.get("data");
          if(secondScreenH5Dialog!=null){
            secondScreenH5Dialog.h5GetShoppingCart(json2);
          }
        }else if("H5SaveValue".equalsIgnoreCase(t2)){
          Map map1= (Map) m1.get("data");
          if(secondScreenH5Dialog!=null){
            secondScreenH5Dialog.h5GetSaveValue((String) map1.get("key"), (String) map1.get("value"));
          }

        }



      }
    }catch (Exception e){
      L.sdk(e);
    }

    result.success("");
  }

  //android api
  private void methodCall_XAndroid(MethodCall call, Result result){
    String json=call.arguments.toString();
    L.sdk("---XAndroid json:"+json);
    XBeanPluginMethod methodCommand= XJsonUtils.json2Obj(json, XBeanPluginMethod.class);

    try{
      if ("goBackToScreen".equalsIgnoreCase(methodCommand.type)){
        L.sdk("---h5调用goBackToScreen");
        api.goBackToScreen();
      }else if ("checkInstallPermission".equalsIgnoreCase(methodCommand.type)){
        L.sdk("---h5调用checkInstallPermission");
        api.checkInstallPermission();
      }else if("check_FOREGROUND_SERVICE_Permission".equalsIgnoreCase(methodCommand.type)){
        api.requestPermission_FOREGROUND_SERVICE(activity);
      }else if("sendBroadcast".equalsIgnoreCase(methodCommand.type)){
        String json1=(String) methodCommand.data;
        Map<String,Object> m1=XJsonUtils.jsonToMapObject(json1);
        String action=(String)m1.get("action");
        Map<String,Object> m2=(Map<String,Object>)m1.get("mapData");
        //
        if(m2!=null && action!=null){
          //
          Intent intent = new Intent(action);
          for (Map.Entry<String, Object> entry : m2.entrySet()) {
            //
            Object ov=entry.getValue();
            L.sdk("---h5调用sendBroadcast发广播,key="+entry.getKey()+",value="+ov);
            if(ov instanceof String){
              intent.putExtra(entry.getKey(), (String)entry.getValue());
            }else if(ov instanceof Boolean){
              intent.putExtra(entry.getKey(), (Boolean)entry.getValue());
            }else if(ov instanceof Double){
              intent.putExtra(entry.getKey(), (Double)entry.getValue());
            }else if(ov instanceof Integer){
              intent.putExtra(entry.getKey(), (Integer)entry.getValue());
            }else if(ov instanceof Long){
              intent.putExtra(entry.getKey(), (Long)entry.getValue());
            }
          }
          applicationContext.sendBroadcast(intent);
        }
      }
    }catch (Exception e){
      L.sdk(e);
    }

    result.success("");
  }



  //串口 4线 商米机///////////XSer////////////////////////////////
  XSerialPortConnectApi serialPortConnectApi;
  private void methodCall_SerialPort(MethodCall call, Result result){
    String json=call.arguments.toString();
    XBeanPluginMethod methodCommand= XJsonUtils.json2Obj(json, XBeanPluginMethod.class);
    if ("connect".equalsIgnoreCase(methodCommand.type)){
      L.sdk("---连接串口电子秤");
      String data= (String) methodCommand.data;

      if(data.contains("SUNMI")){

        serialPortConnectApi=new XSerialPortConnectApi();
        //注意:不添加接收监听serialPortConnectApi.setReceiveMsgCallback 会报错崩溃

        if("SUNMI_T1".equalsIgnoreCase(data)){
          //商米t1机型
          serialPortConnectApi.initSerialPort(
                  "/dev/ttyHSL1",
                  9600,
                  16,
                  "tag_weigher"
          );

        }else if("SUNMI_T2".equalsIgnoreCase(data)){
          //商米t2机型
          serialPortConnectApi.initSerialPort(
                  "/dev/ttyHSL3",
                  9600,
                  16,
                  "tag_weigher"
          );
        }else if("SUNMI_T2s".equalsIgnoreCase(data)){
          //商米t2s机型
          L.sdk("---商米t2s机型");
          serialPortConnectApi.initSerialPort(
                  "/dev/ttyS1",
                  9600,
                  16,
                  "tag_weigher"
          );
        }else if("SUNMI_D2".equalsIgnoreCase(data)){
          //商米t2s机型
          L.sdk("---商米D2机型");
          serialPortConnectApi.initSerialPort(
                  "/dev/ttyS0",
                  9600,
                  16,
                  "tag_weigher"
          );
        }

        serialPortConnectApi.setReceiveMsgCallback(new XSerialPortConnectApi.XISerialPortMsgCallback() {
          @Override
          public void onReceiveData(SphCmdEntity sphCmdEntity) {
            try{
              String value=sphCmdEntity.commandsHex;
              L.sdk("---电子秤value原始值commandsHex= "+value);

              double weigherValue=0;
              if(value.length()==32){
                //大华ACS-30AB
                String a=value.substring(1,2)+value.substring(3,4);
                String b=value.substring(5,6)+value.substring(7,8)+value.substring(9,10);
                weigherValue=Double.parseDouble(a)+Double.parseDouble(b)/1000;
              }else{
                //大华
                value=value.substring(4);
                String a=value.substring(1,2)+value.substring(3,4);
                String b=value.substring(5,6)+value.substring(7,8)+value.substring(9,10);
                weigherValue=Double.parseDouble(a)+Double.parseDouble(b)/1000;
              }

              //L.sdk("---kg="+kg);
              //result.success(String.valueOf(weigherValue));//只返回一次
              nativeSendMessageToFlutter("weigher",String.valueOf(weigherValue));
            }catch (Exception e){
              //
            }
          }
        });


      }else if("ZhiQ-R68P".equalsIgnoreCase(data)){
        L.sdk("---中崎ZhiQ-R68P机型");
        XZhongQiUtils.connectSerial(applicationContext, "ttyS4:9600", new ZQSerialWeigherCallback() {
          @Override
          public void callback(String state, String value) {
            L.sdk("---中崎ZhiQ-R68P,state="+state+",value="+value);
            nativeSendMessageToFlutter("weigher",value);
          }
        });
      }else if("serial_disconnect".equalsIgnoreCase(data)){
        L.sdk("---serial_disconnect 串口设备断开连接");
        //
        XZhongQiUtils.disconnect();
        //
        if(serialPortConnectApi!=null){
          serialPortConnectApi.closeSerialPort();
        }
      }else if("rk3288".equalsIgnoreCase(data)){
        //润农rk3288机型

        serialPortConnectApi=new XSerialPortConnectApi();
        //注意:不添加接收监听serialPortConnectApi.setReceiveMsgCallback 会报错崩溃

        serialPortConnectApi.initSerialPort(
                "/dev/ttyS4",
                9600,
                16,
                2,
                8,
                'N',
                1,
                "tag_weigher"
        );

        serialPortConnectApi.setReceiveMsgCallback(new XSerialPortConnectApi.XISerialPortMsgCallback() {
          @Override
          public void onReceiveData(SphCmdEntity sphCmdEntity) {
            try{
              String value=XStringUtils.bytesToStringGBK(sphCmdEntity.commands);

              if(!XStringUtils.isEmpty(value) && value.contains("kg")){
                int index1=value.indexOf("+");
                int index2=value.indexOf("kg");
                value=value.substring(index1+1,index2);

                double weigherValue=Double.parseDouble(value);
                nativeSendMessageToFlutter("weigher",String.valueOf(weigherValue));

              }


            }catch (Exception e){
              //
            }
          }
        });

      }else if(data.contains("/dev/")){
        //自定义地址
        L.sdk("---自定义SerialPort地址");

        serialPortConnectApi=new XSerialPortConnectApi();
        //注意:不添加接收监听serialPortConnectApi.setReceiveMsgCallback 会报错崩溃

        serialPortConnectApi.initSerialPort(
                data,
                9600,
                16,
                "tag_custom_port"
        );

        //注意:不添加接收监听会报错崩溃
        serialPortConnectApi.setReceiveMsgCallback(new XSerialPortConnectApi.XISerialPortMsgCallback() {
          @Override
          public void onReceiveData(SphCmdEntity sphCmdEntity) {
            try{
              String value=XStringUtils.bytesToStringGBK(sphCmdEntity.commands);
              L.sdk("---自定义SerialPort地址,value="+value);

            }catch (Exception e){
              //
            }
          }
        });

        //L.sdk("---自定义SerialPort地址,sendMsg");
        //serialPortConnectApi.sendMsg(XStringUtils.stringToBytesGBK("啊啊啊啊啊1234\n"));

      }

      result.success("");
    }
  }


  //商米机sdk功能方法/////////////////////////////////////////////////

  private void methodCall_XShangMi(MethodCall call, Result result){
    String json=call.arguments.toString();
    XBeanPluginMethod methodCommand= XJsonUtils.json2Obj(json, XBeanPluginMethod.class);
    if ("init".equalsIgnoreCase(methodCommand.type)){
      L.sdk("---商米sdk初始化");
      XShangMiUtils.initPrinter(applicationContext);
      XShangMiUtils.initSecondScreen(applicationContext);
    }else if("openDrawer".equalsIgnoreCase(methodCommand.type)){
      L.sdk("---商米打开钱箱");
      XShangMiUtils.openDrawer();
    }else if("cutPaper".equalsIgnoreCase(methodCommand.type)){
      L.sdk("---商米切纸");
      XShangMiUtils.cutPaper();
    }else if("printMsg".equalsIgnoreCase(methodCommand.type)){
      L.sdk("---商米打印msg");
      String msg= (String) methodCommand.data;
      XShangMiUtils.printMessage(msg);
    }else if("printBytes".equalsIgnoreCase(methodCommand.type)){
      L.sdk("---商米打印Bytes");
      String msg_json= (String) methodCommand.data;
      List<Byte> list=XJsonUtils.jsonToListX(msg_json,Byte.class);
      byte[] bytes=new byte[list.size()];
      int size=list.size();
      for(int i=0;i<size;i++){
        bytes[i]=list.get(i);
      }
      XShangMiUtils.printByteData(bytes);
    }

    result.success("");

  }





}
